package com.sf.fy.uav.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sf.fy.uav.common.enums.EjectFrequencyEnum;
import com.sf.fy.uav.common.enums.PopUpScreenStatusEnum;
import com.sf.fy.uav.common.enums.SettingStatusEnum;
import com.sf.fy.uav.common.enums.SubjectEnum;
import com.sf.fy.uav.common.request.operate.PopScreenReq;
import com.sf.fy.uav.common.request.operate.PopScreenRequest;
import com.sf.fy.uav.common.response.operational.PopUpScreenResponse;
import com.sf.fy.uav.common.utils.BeanUtil;
import com.sf.fy.uav.common.utils.DateUtils;
import com.sf.fy.uav.common.utils.Rs;
import com.sf.fy.uav.controller.RecordModuleDurationRest;
import com.sf.fy.uav.entity.PopUpScreen;
import com.sf.fy.uav.entity.RecordModuleDuration;
import com.sf.fy.uav.mapper.PopUpScreenMapper;
import com.sf.fy.uav.service.IPopUpScreenService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author LTQ
 * @since 2023-11-20
 */
@Service
public class PopUpScreenServiceImpl extends ServiceImpl<PopUpScreenMapper, PopUpScreen> implements IPopUpScreenService {

    @Autowired
    private PopUpScreenMapper popUpScreenMapper;

    @Autowired
    private RecordModuleDurationRest recordModuleDurationRest;

    private static final Integer CONST = 0;

    private static final String CHECK_SORT = "^[0-9]*$";

    private static final Integer START_NUM = 1;

    private static final Integer END_NUM = 999;

    @Override
    public List<PopUpScreenResponse> getPopUpScreen() {
        /**
         * 1.按照序号倒序排列
         * 2.在开始和结束时间范围内
         */
        Date date = new Date();
        QueryWrapper<PopUpScreen> popUpScreenQueryWrapper = new QueryWrapper<>();
        popUpScreenQueryWrapper.eq("deleted", false);
        popUpScreenQueryWrapper.le("start_time", date);
        popUpScreenQueryWrapper.ge("end_time", date);
        popUpScreenQueryWrapper.ne("status", SettingStatusEnum.OFF.getStatus());
        popUpScreenQueryWrapper.orderByAsc("sort");
        List<PopUpScreen> popUpScreens = popUpScreenMapper.selectList(popUpScreenQueryWrapper);

        List<PopUpScreenResponse> popUpScreenResponses = new ArrayList<>();
        for (PopUpScreen popUpScreen : popUpScreens) {
            Integer ejectFrequency = popUpScreen.getEjectFrequency();
            String id = popUpScreen.getId();
            if (ejectFrequency.equals(EjectFrequencyEnum.ONCE.getCode())) {
                Long times = recordModuleDurationRest.countBySubjectId(id, SubjectEnum.POP_UP_TIMES.getCode());
                if (times > 0) {
                    continue;
                }
            } else if (ejectFrequency.equals(EjectFrequencyEnum.EVERY_FEW_DAYS.getCode())) {
                Integer days = popUpScreen.getDays();
                if (!ObjectUtils.isEmpty(days)) {
                    RecordModuleDuration recordModuleDuration = recordModuleDurationRest.selectLastBySubjectId(id, SubjectEnum.POP_UP_TIMES.getCode());
                    if (!ObjectUtils.isEmpty(recordModuleDuration)) {
                        Integer diffDays = DateUtils.differentDays(recordModuleDuration.getCreateTime(), new Date());
                        if (diffDays < days) {
                            continue;
                        }
                    }
                }
            }
            PopUpScreenResponse popUpScreenResponse = BeanUtil.copyProperties(popUpScreen, PopUpScreenResponse.class);
            popUpScreenResponses.add(popUpScreenResponse);
        }
        return popUpScreenResponses;
    }

    @Override
    public Page<PopUpScreen> getPopUpScreenPageList(PopScreenRequest popScreenRequest) {
        Page<PopUpScreen> page = new Page<>(popScreenRequest.getPage(), popScreenRequest.getSize());
        LambdaQueryWrapper<PopUpScreen> wrapper = Wrappers.lambdaQuery();
        wrapper.like(StringUtils.isNotBlank(popScreenRequest.getTitle()), PopUpScreen::getTitle, popScreenRequest.getTitle())
                .eq(!ObjectUtils.isEmpty(popScreenRequest.getStatus()), PopUpScreen::getStatus, popScreenRequest.getStatus())
                .eq(PopUpScreen::getDeleted, false)
                .orderByDesc(PopUpScreen::getCreateTime);
        return popUpScreenMapper.selectPage(page, wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Rs<Integer> savePopScreen(PopScreenReq popScreenReq) {
        Date date = new Date();
        if (popScreenReq.getStartTime().after(popScreenReq.getEndTime())) {
            throw new RuntimeException("开始时间不能大于结束时间!");
        }
        if (!popScreenReq.getSort().toString().matches(CHECK_SORT)) {
            throw new RuntimeException("序号仅支持输入正整数!");
        }
        if (popScreenReq.getSort() < START_NUM || popScreenReq.getSort() > END_NUM) {
            throw new RuntimeException("序号输入范围[1,999]");
        }
        if (StringUtils.isBlank(popScreenReq.getProcessedBy())) {
            throw new RuntimeException("处理人不能为空!");
        }
        commonRepeatSortCheck(popScreenReq);
        PopUpScreen popUpScreen = BeanUtil.copyProperties(popScreenReq, PopUpScreen.class);
        popUpScreen.setStatus(PopUpScreenStatusEnum.NOT_STARTED.getStatus());
        popUpScreen.setCreateTime(date);
        popUpScreen.setUpdateTime(date);
        int cnt = popUpScreenMapper.insert(popUpScreen);
        if (cnt > CONST) {
            return Rs.success(cnt);
        } else {
            return Rs.failed();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Rs<Integer> updateEntiyById(PopScreenReq popScreenReq) {
        commonCheck(popScreenReq);
        commonRepeatSortCheck(popScreenReq);
        PopUpScreen popUpScreen = BeanUtil.copyProperties(popScreenReq, PopUpScreen.class);
        Date date = new Date();
        popUpScreen.setUpdateTime(date);
        int cnt = popUpScreenMapper.updateById(popUpScreen);
        if (cnt > CONST) {
            return Rs.success(cnt);
        } else {
            return Rs.failed();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Rs<Integer> delPopScreenById(PopScreenReq popScreenReq) {
        commonCheck(popScreenReq);
        PopUpScreen popUpScreen = BeanUtil.copyProperties(popScreenReq, PopUpScreen.class);
        Date date = new Date();
        popUpScreen.setUpdateTime(date);
        popUpScreen.setDeleted(true);
        int cnt = popUpScreenMapper.updateById(popUpScreen);
        if (cnt > CONST) {
            return Rs.success(cnt);
        } else {
            return Rs.failed();
        }
    }

    @Override
    public List<PopUpScreen> getNoStartPopUpScreen() {
        //开始时间超过或刚好等于了当前时间还未开始的 未开始弹屏记录
        return popUpScreenMapper.selectList(new QueryWrapper<PopUpScreen>().eq("status", PopUpScreenStatusEnum.NOT_STARTED.getStatus()).le("start_time", new Date()).eq("deleted", false));
    }

    @Override
    public List<PopUpScreen> getInProgressPopUpScreen() {
        //结束时间已超过当前时间或刚等于当前时间还没有结束的 进行中弹屏记录
        return popUpScreenMapper.selectList(new QueryWrapper<PopUpScreen>().eq("status", PopUpScreenStatusEnum.ON_DISPLAY.getStatus()).le("end_time", new Date()).eq("deleted", false));
    }

    private void commonCheck(PopScreenReq popScreenReq) {
        if (StringUtils.isBlank(popScreenReq.getId())) {
            throw new RuntimeException("弹屏id不能为空!");
        }
        if (StringUtils.isBlank(popScreenReq.getProcessedBy())) {
            throw new RuntimeException("处理人不能为空!");
        }
    }

    private void commonRepeatSortCheck(PopScreenReq popScreenReq) {
        List<PopUpScreen> popUpScreens = popUpScreenMapper.selectList(new QueryWrapper<PopUpScreen>().eq("status", PopUpScreenStatusEnum.ON_DISPLAY.getStatus()).or().eq("status", PopUpScreenStatusEnum.NOT_STARTED.getStatus()).eq("deleted", false));
        if (!CollectionUtils.isEmpty(popUpScreens)) {
            Map<String, Integer> popUpScreenIdAndSortMap = popUpScreens.stream().collect(Collectors.toMap(PopUpScreen::getId, PopUpScreen::getSort, (value1, value2) -> value1));
            List<Integer> sortList = new ArrayList<>(popUpScreens.stream().map(PopUpScreen::getSort).toList());
            if (StringUtils.isNotBlank(popScreenReq.getId())) {
                sortList.remove(popUpScreenIdAndSortMap.get(popScreenReq.getId()));
            }
            if (!ObjectUtils.isEmpty(popScreenReq.getSort()) && sortList.contains(popScreenReq.getSort())) {
                throw new RuntimeException("序号重复,请重新填写!");
            }
            if(StringUtils.isNotBlank(popScreenReq.getJumpLink())&&ObjectUtils.isEmpty(popScreenReq.getJumpType())){
                throw new RuntimeException("有跳链必须选择类型!");
            }
        }
    }
}
